<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="author" content="xmy6364">
    <meta name="description" content="想要成为大佬">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />

    <link rel="shortcut icon" href="/assets/favicon.ico" type="image/x-icon">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@600&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.5.0/styles/default.min.css">
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.5.0/styles/github-gist.min.css">
    <link rel="stylesheet" href="/assets/lib/css/font-awesome.min.css">
    <link rel="stylesheet" href="/assets/css/layout.css" />
    <script defer src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"></script>
    <script defer src="/assets/js/copyCode.js"></script>
    <script defer src="/assets/js/backTop.js"></script>
    <script defer src="/assets/js/tool.js"></script>

    
  <link rel="stylesheet" href="/assets/css/page.css" />
  <link rel="stylesheet" href="/assets/css/sidebar.css" />
  <link rel="stylesheet" href="/assets/css/footer.css" />
  <link rel="stylesheet" href="/assets/css/post.css" />
  <script defer src="/assets/js/backHome.js"></script>
  <script defer src="/assets/js/toc.js"></script>
  <script defer src="/assets/js/copyright.js"></script>


    <title>JavaScript的事件循环机制（Event Loop）</title>
  </head>
  <body>
    <div class="container">
      <aside>
        
  <div class="sidebar">
  <header>梦的博客</header>
  <div class="info">
    <div class="avatar">
      <img src="https://cdn.jsdelivr.net/gh/xmy6364/blog-image/img/pixelartoc_1.png" alt="头像">
    </div>
    <div class="author">xmy6364</div>
    <div class="description">想要成为大佬</div>
    <div class="about">
      <a href="/about">about me.</a>
    </div>
  </div>
  <div class="links">
    <ul>
    
      <li class="links-item">
        <a href="https://github.com/xmy6364" target="_blank">
          <i class="fa fa-github-alt" aria-hidden="true"></i>
        </a>
      </li>
    
      <li class="links-item">
        <a href="tencent://message/?uin=1176281967" target="_blank">
          <i class="fa fa-qq" aria-hidden="true"></i>
        </a>
      </li>
    
    </ul>
  </div>
  <nav>
    <ul>
    
      <li class="nav-item">
        <a href="/archives">
          <span class="nav-item__count">33</span>
          <span class="nav-item__label">归档</span>
        </a>
      </li>
    
      <li class="nav-item">
        <a href="/categories">
          <span class="nav-item__count">2</span>
          <span class="nav-item__label">分类</span>
        </a>
      </li>
    
      <li class="nav-item">
        <a href="/tags">
          <span class="nav-item__count">45</span>
          <span class="nav-item__label">标签</span>
        </a>
      </li>
    
    </ul>
  </nav>
  <div class="catalogue" id="catalogue"></div>
</div>

      </aside>
      <main>
        
  <div class="post">
    <div class="post-front">
      <h1 class="post-front__title">JavaScript的事件循环机制（Event Loop）</h1>
      <div class="post-front__desc">
        
        <p class="post-front__desc-date">
          <i class="fa fa-calendar" aria-hidden="true"></i>
          2021/05/17 17:12:32
        </p>
        
        
        <p class="post-front__desc-category">
          <i class="fa fa-folder-o" aria-hidden="true"></i>
          <a href="/categories/技术">
            技术
          </a>
        </p>
        
          <div class="post-front__desc-tags">
          
          <a href="/tags/JavaScript">
            <i class="fa fa-tag" aria-hidden="true"></i>
            JavaScript
          </a>
          
        </div>
      </div>
    </div>
    <div class="post-content">
      <nav id="toc" class="toc"><ol><li><a href="#单线程">单线程</a></li><li><a href="#执行栈与任务队列">执行栈与任务队列</a></li><li><a href="#微任务与宏任务">微任务与宏任务</a></li></ol></nav><p>事件循环机制是JavaScript运行的核心，因此要想写出bug少的js代码就必须要了解这个机制是如何运作的，以及为什么会有这个机制。</p>
<p>本篇文章是我对Event Loop的理解</p>
<h2 id="单线程">单线程</h2>
<p>JavaScript是一个单线程的非阻塞的脚本语言，也就是说JavaScript在同一时间只能做一件事。那么，为什么JavaScript不能有多个线程呢？</p>
<p>在最开始JavaScript还不像现在是一个全能的语言，那个时候它只有一个任务，就是作为浏览器的脚本，与用户互动和操作DOM。这就决定了它只能是单线程的，不然会带来很复杂的问题。比如：如果JavaScript有两个线程，一个线程在某个DOM节点上添加了内容，而另一个线程删除了这个节点，那么这个时候应该以哪个线程为准？</p>
<p>所以在最开始JavaScript命中注定是单线程的语言。</p>
<blockquote>
<p>HTML5之后提出了Web Worker，为JavaScript提供了多线程环境，但是子线程完全受主线程控制并且不能操作DOM，因此并没有改变JavaScript单线程的本质</p>
</blockquote>
<h2 id="执行栈与任务队列">执行栈与任务队列</h2>
<p>为了解决单线程导致的CPU利用率低以及后一个任务必须等待前一个任务结束才能执行的问题，JavaScript将所有任务分成了<strong>同步任务</strong>和<strong>异步任务</strong>，同步任务会在进入主线程<strong>执行栈</strong>，而异步任务会进入<strong>任务队列</strong>等执行栈所有任务执行完毕后才会进入执行栈执行。</p>
<blockquote>
<p>JavaScript是单线程的，但是JavaScript的执行环境不是，浏览器会为异步任务单独开一个线程，也就是任务队列</p>
</blockquote>
<p>主线程会不断重复以下三个步骤：</p>
<ol>
<li>同步任务进入执行栈执行</li>
<li>异步任务进入主线程之外的任务队列</li>
<li>执行栈中的所有同步任务执行完毕后，读取任务队列中的任务，放入执行栈中执行</li>
</ol>
<h2 id="微任务与宏任务">微任务与宏任务</h2>
<p>异步任务又被分为<strong>微任务</strong>和<strong>宏任务</strong>，它们之间的执行优先级并不相同，微任务总会在宏任务之前执行，也就是说：同步任务&gt;微任务&gt;宏任务。</p>
<blockquote>
<p>在浏览器中，微任务的任务队列会在每个宏任务执行完后执行</p>
<p>老版本的Nodejs中有所不同，微任务会在事件循环的各个阶段之间执行</p>
<p>Nodejs V11之后就与浏览器的机制相同了</p>
</blockquote>
<p>微任务：</p>
<ul>
<li>Promise的<code>Promise.then</code>`Promise.catch<code>\</code>Promise.finally`</li>
<li>MutationObserver（可以用来监听DOM变动）</li>
<li><code>proccess.nextTick</code>（nodejs独有）</li>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask">queueMicrotask</a></li>
</ul>
<p>宏任务：</p>
<ul>
<li>script标签中的代码</li>
<li>事件触发的回调函数，如：DOM的事件回调、<code>requestAnimationFrame</code>、IO操作</li>
<li>定时器的回调函数</li>
</ul>
<p>可能还会完善...</p>

    </div>
    
  </div>

        <footer>
        
  <div class="footer">
  
  <div class="theme">
    博客主题为 <a href="https://github.com/xmy6364/CoinRailgun">CoinRailgun</a> 默认主题
  </div>
  <div class="copyright">
    <span>© 2019-2021 xmy6364.</span>
    <span>Powered by <a href="https://github.com/xmy6364/CoinRailgun">CoinRailgun</a></span>
  </div>
</div>

        </footer>
      </main>
    </div>
  </body>
</html>
